package com.vshop.timingtask;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.vshop.entity.comentity.DevicePackagesRelation;
import com.vshop.entity.comentity.PartnerInfo;
import com.vshop.entity.newpojo.TurntoInterfaceUtils;
import com.vshop.entity.newpojo.request.RequestBody.SyncPackageAndDeviceRequestBody;
import com.vshop.entity.newpojo.request.RequestHeader;
import com.vshop.entity.newpojo.request.subRequest.SyncPackageAndDeviceRequest;
import com.vshop.entity.newpojo.response.subResponse.SyncPackageAndDeviceResponse;
import com.vshop.entity.newpojo.response.subResponse.common._DevicePackages;
import com.vshop.entity.newpojo.response.subResponse.common._PackageCodeList;
import com.vshop.entity.newpojo.response.subResponse.common._PackagesDevice;
import com.vshop.entity.requestinterface.Constant;
import com.vshop.entity.requestinterface.syncrelation.request.RequestSyncDevicePackages;
import com.vshop.entity.requestinterface.syncrelation.response.ResponseSyncDevicePackages;
import com.vshop.service.DevicePackagesRelationService;
import com.vshop.service.PartnerInfoService;
import com.vshop.service.PartnerPackageService;
import com.vshop.service.task.ServicePlanTaskServiceImpl;
import com.vshop.utils.HttpClientTool;
import com.vshop.utils.HttpUtil;
import com.vshop.utils.JaxbUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * http://localhost:8086/vshop/syncPackageAndDeviceTask
 * <p>
 * 每天凌晨4点执行一次，晚上23点执行一次
 *
 * @author lm
 * @date 2019/5/24
 */
@Configuration
@EnableScheduling
@RestController
@Slf4j
public class SyncDeviceTask {
    @Value("${xmlIot.BASE_URL}")
    private String BASE_URL;
    @Value("${system.autoTask}")
    private boolean autoTask;

    @Autowired
    DevicePackagesRelationService devicePackagesRelationService;
    @Autowired
    PartnerInfoService partnerInfoService;
    @Autowired
    PartnerPackageService packageService;
    @Autowired
    ServicePlanTaskServiceImpl taskService;

    //@Scheduled(cron = "0 2 22 * * ?")
    @GetMapping(value = "syncDeviceTask")
    @Async

    public void execute() {
        if (autoTask) {
            syncDeviceTask();
        }
    }

    public void syncDeviceTask() {

        log.info("每1天下午晚上22点执行一次的syncDeviceTask开始执行！");
        List<PartnerInfo> partnerList = taskService.findPartnerCode("");

        if (null == partnerList || 0 >= partnerList.size() || partnerList.isEmpty()) {
            log.info("partnerList==null");
            return;
        }

        partner:
        for (PartnerInfo partner : partnerList) {

            if (StringUtils.isBlank(partner.getPartnerCode()) || StringUtils.isBlank(partner.getPartnerIndex()) || StringUtils.isBlank(partner.getPartnerName())) {
                log.info("partnerCode==null");
                continue partner;
            }

            //现在去数据库比对当前partnerCode是否是需要去同步套餐和设备的,如果在列表中有记录可以理解返回
            if (taskService.queryOrNotPartnerCode(partner.getPartnerCode()) >= 1) {
                log.info(partner.getPartnerCode() + "：无需请求列表企业");
                continue;
            }

            //把有用的参数拿出来
            String partnerCode = partner.getPartnerCode();
            String secret = partner.getSecret();
            String partnerName = partner.getPartnerName();
            Integer partnerIndex = Integer.parseInt(partner.getPartnerIndex());

            //下面开始正式请求了
            RequestSyncDevicePackages sync = new RequestSyncDevicePackages();
            sync.setPageNo(1);
            sync.setPageSize(1);
            sync.setPartnerCode(partnerCode);

            String requestInterface = JSON.toJSONString(sync);
            log.info("【syncDeviceTask】数量请求：" + requestInterface);
            String url = "http://localhost:8085/iot" + Constant.iot_syncPackageAndDevice;
            // 发送post请求，并接收返回结果
            String returnStr = HttpUtil.httpPost(url, requestInterface);
            log.info("url=" + url);
            log.info("【syncDeviceTask】数量响应：" + returnStr);
            ResponseSyncDevicePackages response = JSONArray.parseObject(returnStr, ResponseSyncDevicePackages.class);

            if (null == response || "".equals(response) || null == response.getPage() || 0 >= response.getPage().getTotalCount()) {
                log.info(partnerCode + "：返回ResponseSyncDevicePackages==null");
                continue partner;
            }

            //totalCount一定大于0
            int totalCount = response.getPage().getTotalCount();
            double total;
            String deviceId;

            if (Math.ceil(totalCount / 1000) < 1) {
                total = 1;
            } else {
                total = Math.ceil(totalCount / 1000) + 1;
            }

            count:
            for (int x = 1; x <= total; x++) {

                log.info("正在查询的企业是：" + partnerCode + ";syncDeviceTask::::totalCount是：" + totalCount + ";total是：" + total + ";x是：" + x);

                SyncPackageAndDeviceRequest request = new SyncPackageAndDeviceRequest();
                TurntoInterfaceUtils utils = new TurntoInterfaceUtils();

                RequestHeader header = utils.getRequestHeader("batchSynDevicePackages", "GMSYS");
                request.setHeader(header);

                SyncPackageAndDeviceRequestBody body = new SyncPackageAndDeviceRequestBody();
                body.setPartnerCode(partnerCode);
                body.setPageNo(Integer.toString(x));
                body.setPageSize("1000");

                request.setBody(body);
                String sign = "";
                try {
                    sign = utils.getSign(header, body, body.getClass(), "wORfzY1DbaB39RJ4s82QxGs8bSGfeU8z");
                } catch (Exception e) {
                    log.info(partnerCode + "请求接口:batchSynDevicePackages,签名有误；" + e);
                    continue partner;
                }
                request.setSign(sign);

                // 将参数转换成XML格式
                String sRequest = new JaxbUtil(SyncPackageAndDeviceRequest.class).toXml(request, "utf-8");
                log.info("【syncDeviceTask】请求：" + sRequest);
                // 发送post请求，并接收返回结果
                String result = HttpClientTool.sendHttpPost(BASE_URL, sRequest);
                log.info("url=" + BASE_URL + ";接口名：" + Constant.cmd_syncPackageAndDevice);
                log.info("【syncDeviceTask】响应：" + result);

                boolean b2 = null == result || "".equals(result) || "-1".equals(result);
                if (b2) {
                    log.info(partnerCode + "：返回result==null或者-1");
                    continue count;
                }

                // 将回传的xml转换成object数据
                SyncPackageAndDeviceResponse responseObj = new JaxbUtil(SyncPackageAndDeviceResponse.class).fromXml(result, "utf-8");

                boolean b3 = null == responseObj || StringUtils.isBlank(responseObj.getHeader().getResultCode()) || !"0000".equals(responseObj.getHeader().getResultCode());
                if (b3) {
                    log.info(partnerCode + "：返回responseObj==null或者retCode！=0000");
                    continue count;
                }

                boolean b4 = null == responseObj.getBody().getDevice_packages() || responseObj.getBody().getDevice_packages().size() <= 0 || responseObj.getBody().getDevice_packages().isEmpty();
                if (b4) {
                    log.info(partnerCode + "：返回getDevice_packages()==null");
                    continue count;
                }

                List<_DevicePackages> deviceList = responseObj.getBody().getDevice_packages();

                deviceList:
                for (_DevicePackages d : deviceList) {

                    boolean b5 = StringUtils.isBlank(d.getDeviceId()) || null == d.getPackages() || 0 >= d.getPackages().size() || d.getPackages().isEmpty();
                    if (b5) {
                        log.info(partnerCode + "：返回deviceList==null或者d.getDeviceId()==null");
                        continue;
                    }

                    deviceId = d.getDeviceId();
                    List<_PackagesDevice> packageList = d.getPackages();

                    packageList:
                    for (_PackagesDevice p : packageList) {

                        boolean b6 = null == p.getPackage_list() || 0 >= p.getPackage_list().size() || p.getPackage_list().isEmpty();
                        if (b6) {
                            log.info(partnerCode + "：返回p.getPackage_list()==null");
                            continue;
                        }

                        List<_PackageCodeList> codeList = p.getPackage_list();

                        codeList:
                        for (_PackageCodeList code : codeList) {

                            boolean b7 = null == code.getPackageCode() || 0 >= code.getPackageCode().size() || code.getPackageCode().isEmpty();
                            if (b7) {
                                log.info(partnerCode + "：返回code.getPackageCode()==null");
                                continue;
                            }

                            List<String> packageCodeList = code.getPackageCode();

                            packageCodeList:
                            for (String s : packageCodeList) {

                                if (StringUtils.isBlank(s)) {
                                    log.info(partnerCode + "：返回code为空或者null");
                                    continue;
                                }

                                String packageCode = s;
                                String packageName = packageService.queryPackageNameByCode(packageCode, partnerCode);

                                switch (partnerIndex) {
                                    case 0:
                                        int c0 = this.devicePackagesRelationService.findCountByCondition_0(packageCode, partnerCode, deviceId);
                                        if (c0 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_0(relation);
                                        }
                                        break;

                                    case 1:
                                        int c1 = this.devicePackagesRelationService.findCountByCondition_1(packageCode, partnerCode, deviceId);
                                        if (c1 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_1(relation);
                                        }
                                        break;

                                    case 2:
                                        int c2 = this.devicePackagesRelationService.findCountByCondition_2(packageCode, partnerCode, deviceId);
                                        if (c2 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_2(relation);
                                        }
                                        break;

                                    case 3:
                                        int c3 = this.devicePackagesRelationService.findCountByCondition_3(packageCode, partnerCode, deviceId);
                                        if (c3 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_3(relation);
                                        }
                                        break;

                                    case 4:
                                        int c4 = this.devicePackagesRelationService.findCountByCondition_4(packageCode, partnerCode, deviceId);
                                        if (c4 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_4(relation);
                                        }
                                        break;

                                    case 5:
                                        int c5 = this.devicePackagesRelationService.findCountByCondition_5(packageCode, partnerCode, deviceId);
                                        if (c5 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_5(relation);
                                        }
                                        break;

                                    case 6:
                                        int c6 = this.devicePackagesRelationService.findCountByCondition_6(packageCode, partnerCode, deviceId);
                                        if (c6 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_6(relation);
                                        }
                                        break;

                                    case 7:
                                        int c7 = this.devicePackagesRelationService.findCountByCondition_7(packageCode, partnerCode, deviceId);
                                        if (c7 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_7(relation);
                                        }
                                        break;

                                    case 8:
                                        int c8 = this.devicePackagesRelationService.findCountByCondition_8(packageCode, partnerCode, deviceId);
                                        if (c8 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_8(relation);
                                        }
                                        break;

                                    case 9:
                                        int c9 = this.devicePackagesRelationService.findCountByCondition_9(packageCode, partnerCode, deviceId);
                                        if (c9 <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation_9(relation);
                                        }
                                        break;

                                    default:
                                        int c = this.devicePackagesRelationService.findCountByCondition(packageCode, partnerCode, deviceId);
                                        if (c <= 0) {
                                            DevicePackagesRelation relation = new DevicePackagesRelation();
                                            relation.setPartnerCode(partnerCode);
                                            relation.setPartnerName(partnerName);
                                            relation.setPackageCode(packageCode);
                                            relation.setPackageName(packageName);
                                            relation.setDeviceCode(deviceId);
                                            this.devicePackagesRelationService.storageRelation(relation);
                                        }
                                        break;
                                }

                            }

                        }

                    }

                }

            }

        }
        log.info("每1天下午晚上22点执行一次的syncDeviceTask执行完毕！");
    }
}